<template>
  <div
    v-if="visible"
    ref="menuRef"
    class="liteflow-editor-context-pad"
    :style="{ left: x + 'px', top: y + 'px' }"
  >
    <div class="liteflow-editor-context-pad__header">
      <h3 class="liteflow-editor-context-pad__title">{{ title }}</h3>
    </div>
    <div class="liteflow-editor-context-pad__body">
      <div class="liteflow-editor-context-pad__search">
        <input
          v-model="searchText"
          class="liteflow-editor-context-pad__search-input"
          placeholder="搜索组件..."
          @input="handleSearch"
        />
      </div>
      <div class="liteflow-editor-context-pad__results">
        <div
          v-for="group in filteredGroups"
          :key="group.key"
          class="liteflow-editor-context-pad__group"
        >
          <div class="liteflow-editor-context-pad__group-name">
            {{ group.name }}
          </div>
          <div class="liteflow-editor-context-pad__group-items">
            <div
              v-for="(cellType, index) in group.cellTypes"
              :key="index"
              class="liteflow-editor-context-pad__group-item"
              @click="handleClickMenu(cellType)"
            >
              <img
                class="liteflow-editor-context-pad__group-item-icon"
                :src="cellType.icon"
                :alt="cellType.label"
              />
              <div class="liteflow-editor-context-pad__group-item-label">
                {{ cellType.label }}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { defineComponent, ref, computed, watch, onMounted, onBeforeUnmount, inject } from 'vue';
import { GRAPH_SYMBOL } from './context.js';
import ELBuilder from '../core/model/builder.js';
import { history } from '../core/history/index.js';
import { PALETTE_GROUPS } from '../core/palette/groups.js';
import { getModel } from '../core/state/model.js';

export default defineComponent({
  name: 'ContextPad',
  setup() {
    const { flowGraph, contextPadInfo } = inject(GRAPH_SYMBOL);
    const menuRef = ref(null);
    const searchText = ref('');

    const visible = computed(() => contextPadInfo.visible);
    const x = computed(() => contextPadInfo.x);
    const y = computed(() => contextPadInfo.y);
    const edge = computed(() => contextPadInfo.edge);
    const node = computed(() => contextPadInfo.node);
    const scene = computed(() => contextPadInfo.scene || 'append');
    const title = computed(() => contextPadInfo.title || '插入节点');

    const filteredGroups = computed(() => {
      if (!searchText.value) {
        return PALETTE_GROUPS;
      }
      const search = searchText.value.toLowerCase();
      return PALETTE_GROUPS.map((group) => ({
        ...group,
        cellTypes: group.cellTypes.filter((cellType) =>
          cellType.label.toLowerCase().includes(search)
        ),
      })).filter((group) => group.cellTypes.length > 0);
    });

    const handleSearch = () => {
      // 搜索逻辑已在 computed 中实现
    };

    const handleClickAway = () => {
      console.log('[ContextPad] 关闭 ContextPad');
      if (flowGraph.value) {
        flowGraph.value.trigger('graph:hideContextPad');
        // 清除选中的模型，避免影响后续操作
        flowGraph.value.trigger('settingBar:forceUpdate');
        console.log('[ContextPad] 触发 settingBar:forceUpdate');
      }
    };

    const handleClickMenu = (cellType) => {
      console.log('[ContextPad] 选择节点类型:', cellType.label, '场景:', scene.value);
      if (edge.value) {
        const targetNode = edge.value.getTargetNode();
        const { model: targetModel } = targetNode?.getData() || {};
        const sourceNode = edge.value.getSourceNode();
        const { model: sourceModel } = sourceNode?.getData() || {};
        const inComingEdgesLength = (
          flowGraph.value.getIncomingEdges(targetNode) || []
        ).length;

        if (
          inComingEdgesLength > 1 ||
          (sourceModel && targetModel?.isParentOf(sourceModel))
        ) {
          sourceModel?.append(ELBuilder.createELNode(cellType.type, targetModel));
        } else {
          targetModel?.prepend(ELBuilder.createELNode(cellType.type, targetModel));
        }
        history.push();
      } else if (node.value) {
        const { model } = node.value.getData() || {};
        if (scene.value === 'prepend') {
          model.prepend(ELBuilder.createELNode(cellType.type, model));
        } else if (scene.value === 'replace') {
          model.replace(ELBuilder.createELNode(cellType.type, model));
        } else {
          model.append(ELBuilder.createELNode(cellType.type, model));
        }
        history.push();
        console.log('[ContextPad] history.push 完成');
        
        // 手动再次触发 model:change 以确保画布更新
        if (flowGraph.value) {
          console.log('[ContextPad] 手动触发 model:change');
          console.log('[ContextPad] flowGraph listeners:', flowGraph.value.listeners);
          console.log('[ContextPad] model:change listeners:', flowGraph.value.listeners['model:change']);
          flowGraph.value.trigger('model:change');
        }
      }

      // 打印当前 EL 表达式
      const currentModel = getModel();
      console.log('[ContextPad] 当前 EL 表达式:', currentModel?.toEL(' '));

      // 清除选中状态
      if (flowGraph.value) {
        flowGraph.value.cleanSelection();
        console.log('[ContextPad] 清除选中状态');
      }

      handleClickAway();
    };

    const handleDocumentClick = (event) => {
      if (menuRef.value && !menuRef.value.contains(event.target) && visible.value) {
        handleClickAway();
      }
    };

    watch(visible, (newVal) => {
      if (newVal) {
        searchText.value = '';
      }
    });

    onMounted(() => {
      document.addEventListener('click', handleDocumentClick, true);
    });

    onBeforeUnmount(() => {
      document.removeEventListener('click', handleDocumentClick, true);
    });

    return {
      menuRef,
      searchText,
      visible,
      x,
      y,
      title,
      filteredGroups,
      handleSearch,
      handleClickMenu,
    };
  },
});
</script>

<style lang="less" scoped>
.liteflow-editor-context-pad {
  z-index: 1003;
  position: fixed;
  min-width: 200px;
  box-shadow: 0 3px 6px -4px rgba(0, 0, 0, 0.12),
    0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 9px 28px 8px rgba(0, 0, 0, 0.05);
  background: #fff;
  border-radius: 4px;

  &__header {
    display: flex;
    align-items: stretch;
    line-height: 20px;
    margin: 10px 12px;
  }

  &__title {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 14px;
    margin: 0;
    font-weight: 500;
  }

  &__body {
    padding-bottom: 10px;
  }

  &__search {
    margin: 10px 12px;
  }

  &__search-input {
    padding: 4px 11px;
    font-size: 14px;
    line-height: 1.5;
    border: 1px solid #d9d9d9;
    border-radius: 4px;
    outline: none;
    transition: all 0.2s;

    &:hover {
      border-color: #40a9ff;
    }

    &:focus {
      border-color: #40a9ff;
      box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
    }
  }

  &__results {
    margin: 7px 3px 7px 12px;
    max-height: 280px;
    overflow: auto;
    padding-right: 9px;

    &::-webkit-scrollbar {
      width: 6px;
    }

    &::-webkit-scrollbar-thumb {
      border-radius: 3px;
      background-color: rgba(0, 0, 0, 0.2);
    }

    &::-webkit-scrollbar-track {
      box-shadow: none;
      background: transparent;
      margin: 0;
      padding: 5px;
    }
  }

  &__group {
    margin-bottom: 4px;
  }

  &__group-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: rgba(0, 0, 0, 0.45);
    font-size: 12px;
    padding: 5px 12px;
    min-height: 32px;
  }

  &__group-items {
    /* 分组项目容器 */
  }

  &__group-item {
    display: flex;
    align-items: center;
    min-height: 32px;
    padding: 5px 12px;
    color: rgba(0, 0, 0, 0.88);
    font-size: 14px;
    line-height: 1.5;
    cursor: pointer;
    border-radius: 4px;
    transition: background-color 0.2s;

    &:hover {
      background-color: rgba(0, 0, 0, 0.04);
    }
  }

  &__group-item-icon {
    width: 20px;
    height: 20px;
    margin-right: 8px;
  }

  &__group-item-label {
    flex: auto;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
  }
}
</style>
